import React from 'react';
// import ReactDOM from 'react-dom';
// import './index.css';
// import App from './App';
// import reportWebVitals from './reportWebVitals';

// ReactDOM.render(
//   <React.StrictMode>
//     <App />
//   </React.StrictMode>,
//   document.getElementById('root')
// );

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// reportWebVitals();


const jsx = (
    <div id="a1">
      <div id="b1">
        <div id='c1'></div>
        <div id='c2'></div>
      </div>
      <div id='b2'>
        <div id='c3'></div>
      </div>
    </div>
)

/*
* render阶段
* 构建每一个节点的fiber对象
* 从root构建
* */

const container = document.getElementById("root")

//构建根元素的fiber对象
const workInProgressRoot = {
  stateNode: container,
  props: {
    children: [jsx]
  }
}

// 下一个要执行的任务
let nextUnitOfWork = workInProgressRoot;

// 构建子级fiber
function beginWork(workInProgressFiber) {
  // 1.创建dom对象，并存储到stateNode中
  if (!workInProgressFiber.stateNode) {
    // 创建dom
    workInProgressFiber.stateNode = document.createElement(workInProgressFiber.type)
    // 为dom添加属性
    for(let attr in workInProgressFiber.props) {
      if (attr !== 'children') {
        workInProgressFiber.stateNode[attr] = workInProgressFiber.props[attr]
      }
    }
  }
  // 2.构建当前fiber的子级fiber
  if (Array.isArray(workInProgressFiber.props.children)) {
    let prevFiber = null;
    workInProgressFiber.props.children.forEach((child, index) => {
      let childFiber = {
        type: child.type,
        props: child.props,
        effectTag: 'PLACEMENT',
        return: workInProgressFiber,
      }
      // 只有第一个子级才是父级的child
      if (index === 0) {
        workInProgressFiber.child = childFiber
      } else {
        prevFiber.sibling = childFiber
      }
      // 使用缓存的方式找到上一个子级fiber
      prevFiber = childFiber
    })
  }
}

// 链表 按照顺序存 指针，指向下一个节点
// react的链表存储需要执行dom操作的fiber节点
// 顺序 按照dom操作的顺序 见img.png
// 设置一个变量，缓存尾部fiber，指向尾部
function completeUnitOfWork(workInProgressFiber) {
  // 获取当前fiber的父级
  const returnFiber = workInProgressFiber.return
  // 看父级是否存在
  if (returnFiber) {
    // 判断是否需要执行dom操作 effectTag
    if(workInProgressFiber.effectTag) {
      // 将子树和此 Fiber 的所有副作用附加到父级的 effect 列表上
  
      // 以下两个判断的作用是搜集子 Fiber的 effect 到父 Fiber
      if (!returnFiber.firstEffect) {
        // first
        returnFiber.firstEffect = workInProgressFiber.firstEffect;
      }
  
      if (workInProgressFiber.lastEffect) {
        // last
        returnFiber.lastEffect = workInProgressFiber.lastEffect;
      }
      
      // 第二次构建链表，父级元素的lastEffect已经指向尾部之后
      // 就需要为尾部fiber添加nextEffect指向下一个需要dom操作的对象
      if (returnFiber.lastEffect) {
        returnFiber.lastEffect.nextEffect = workInProgressFiber
      } else {
        returnFiber.firstEffect = workInProgressFiber
      }
      // 父级节点的lastEffect指向尾部
      returnFiber.lastEffect = workInProgressFiber
    }
  }
}

function performUnitOfWork(workInProgressFiber) {
  // 构建子级fiber
  beginWork(workInProgressFiber)
  // 往下走，构建子级的子级
  // 模拟递归的递
  if (workInProgressFiber.child) {
    return workInProgressFiber.child
  }
  
  // 模拟递归的归
  while (workInProgressFiber) {
    // 构建链表
    // 向上从C1开始
    completeUnitOfWork(workInProgressFiber)
    
    // 有同级
    if (workInProgressFiber.sibling) {
      // 返回同级 构建同级的子级
      return workInProgressFiber.sibling
    }
    // 更新父级
    workInProgressFiber = workInProgressFiber.return
  }
}

function workLoop(deadline) {
  // 1.是否有空余时间
  // 2.是否有要执行的任务
  while (nextUnitOfWork && deadline.timeRemaining() > 0) {
    nextUnitOfWork = performUnitOfWork(nextUnitOfWork)
  }
  // 所有任务都完成了
  if (!nextUnitOfWork) {
    // 进入第二阶段
    commitRoot()
  }
}

// commit阶段
function commitRoot () {
  console.log(workInProgressRoot)
}

// 在浏览器空闲时候执行任务
requestIdleCallback(workLoop)

